package cn.easyutil.veteran.core.utils;

import cn.easyutil.veteran.core.error.CommonException;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.util.*;

/**
 * 加签工具
 */
public class SignUtil {

    private String secretName;

    private String secret;

    private final Map<String,String> fields = new HashMap<>();

    private SignUtil(){}


    public static SignUtil builder(String secretName, String secret){

        SignUtil util = new SignUtil();
        util.secretName = secretName;
        util.secret = secret;
        return util;
    }

    public static SignUtil builder(String secret){
        return builder("appSecret",secret);
    }

    public SignUtil addField(String key, String val){
        if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(val)){
            this.fields.put(key,val);
        }
        return this;
    }

    public String toSimpleSign(){
        return toSimpleSign(this.fields);
    }

    /**
     * 简单加签逻辑，默认结果转大写MD5
     * @param params 参数
     * @return  签名
     */
    public String toSimpleSign(Map<?,?> params){
        return toSimpleSign(params,true);
    }

    /**
     * 自然排序
     * 简单加签逻辑 (propertyKey=val&secret=secret方式，最后md5)
     * @param params    参数
     * @param toUpCase  是否将MD5转大写
     * @return  签名
     */
    public String toSimpleSign(Map<?,?> params,boolean toUpCase){
        if(params==null || params.isEmpty()){
            throw new CommonException("签名:缺少必填参数");
        }
        SortedMap<?,?> sortedMap = new TreeMap<>(params);
        // 会
        // “treeMap中的key会自动按照字母排序,也可以利用比较器自定义排序”
        Iterator<? extends Map.Entry<?, ?>> iterator = sortedMap.entrySet().iterator();
        StringBuilder sb = new StringBuilder();
        while (iterator.hasNext()){
            Map.Entry<?, ?> next = iterator.next();
            String key = next.getKey().toString();
            Object value = next.getValue();
            if(value == null){
                continue;
            }
            if(StringUtils.isBlank(value.toString())){
                continue;
            }
            sb.append(key).append("=").append(value.toString()).append("&");
        }
        String str = sb.append(secretName).append("=").append(secret).toString();

        return toUpCase? MD5.create().digestHex(str).toUpperCase(): MD5.create().digestHex(str);
    }
}
